package com.lin.cloud.disk.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lin.cloud.disk.common.enums.EResponseCode;
import com.lin.cloud.disk.common.enums.ResponseCode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.List;

@Data
@ApiModel(value = "响应结果", description = "API响应结果")
public class Result<T> {
    @ApiModelProperty(value = "状态码", name = "code", required = true, example = "00000")
    private String code;
    @ApiModelProperty(value = "响应消息", name = "message", required = true, example = "成功")
    private String message;
    @ApiModelProperty(value = "成功失败", name = "success", required = true, example = "false")
    private boolean success;
    @ApiModelProperty(value = "响应数据", name = "data", required = true, example = "null")
    private T data;

    public Result() {
        this.setResult(EResponseCode.FAIL);
        this.setSuccess(false);
    }

    /**
     * @param message
     */
    public Result(String message) {
        this();
        this.message = message;
    }

    public Result(String code, String message) {
        this.code = code;
        this.message = message;
    }

    public Result(ResponseCode e) {
        this.setResult(e);
    }

    public Result<T> resultFail() {
        this.setResult(EResponseCode.FAIL);
        this.setSuccess(false);
        return this;
    }

    public Result<T> resultSuccess() {
        this.setResult(EResponseCode.SUCCESS);
        this.setSuccess(true);
        return this;
    }

    public void setResult(ResponseCode e) {
        this.code = String.valueOf(e.getCode());
        this.message = e.getDescribe();
    }

    public Result<T> setData(T data) {
        this.data = data;
        return this;
    }

    /**
     * 根据状态返回一个Result
     *
     * @param e 状态码
     * @return 根据这个状态码生成的result
     */
    public static <T> Result<T> status(ResponseCode e) {
        return new Result<T>(e);
    }

    /**
     * 返回成功,并且带上一条消息
     *
     * @param message 需要带回的消息
     * @return 根据消息生成的result
     */
    public static <T> Result<T> success(String message) {
        Result<T> result = new Result<T>().resultSuccess();
        result.setMessage(message);
        return result;
//        return new Result(message).resultSuccess();
    }

    /**
     * 返回成功
     *
     * @return 表示成功的result
     */
    public static <T> Result success() {
        return new Result<T>().resultSuccess();
    }


    /**
     * 返回成功,并且带回所需要的数据
     *
     * @param obj 需要带回的数据
     * @return 成功, 并且带有返回数据的result
     */
    @SuppressWarnings("unchecked")
    public static <T> Result<T> success(T obj) {
        return new Result<T>().resultSuccess().setData(obj);
    }


    /**
     * 返回成功,并且带回分页所需要的数据,需要指明总记录数
     *
     * @param list  本次分页所包含的数据
     * @param total 总记录数
     * @return 成功, 并且带有分页信息的result
     */
    @SuppressWarnings("unchecked")
    public static <T> Result<T> success(List<T> list, Long total) {
        IPage page = new Page();
        page.setRecords(list);
        page.setTotal(total);
        return (Result<T>) success(page);
    }


    /**
     * 返回失败
     *
     * @return 表示失败的result
     */
    public static <T> Result fail() {
        return new Result<T>().resultFail();
    }

    /**
     * 返回失败,并且带上错误信息,默认的错误码是"1111"
     *
     * @param message 失败所包含的信息
     * @return 失败, 并且含有错误信息的result
     */
    public static <T> Result<T> fail(String message) {
        Result<T> result = new Result<T>().resultFail();
        result.setMessage(message);
        return result;

    }

    /**
     * 返回失败
     *
     * @param code
     * @param message
     * @return
     */
    public static <T> Result<T> fail(String code, String message) {
        Result<T> result = new Result<T>().resultFail();
        result.setCode(code);
        result.setMessage(message);
        return result;

    }

    /**
     * 返回失败,并且指定错误信息和错误码
     *
     * @param e 错误码
     * @return 失败, 并且包含指定错误信息和错误码的result
     */
    public static <T> Result<T> fail(ResponseCode e) {
        Result result = new Result();
        result.setResult(e);
        return result;
    }

    @Override
    public String toString() {
        return JSONObject.toJSONString(this);
    }
}

